package com.ding.dailyup.service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.ding.dailyup.config.SystemConfig;
import com.ding.dailyup.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ding.dailyup.constant.StockConstant;
import com.ding.dailyup.model.StockRecommend;
import com.ding.dailyup.repository.StockRecommendRepository;
import com.ding.dailyup.util.DateUtil;
import com.ding.dailyup.util.StockUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpUtil;

@Service
public class StockRecommendService {
	@Autowired
	private StockRecommendRepository stockRecommendRepository;
	@Autowired
	private RedisService redisService;

	public List<StockRecommend> findRecommend(Long strategyId,
			long dateTimestamp) {
		return stockRecommendRepository
				.findByStrategyIdAndStatusAndUploadDate(strategyId, 1,
						DateUtil.getLocalDateTimeFromTimeStamp(dateTimestamp))
				.orElse(Lists.newArrayList());
	}


	public List<StockRecommend> findRecommend(Set<String> stockCodes,
	                                          long dateTimestamp) {
		return stockRecommendRepository
				.findAllByStockCodeInAndStatusAndUploadDate(stockCodes, 1,
						DateUtil.getLocalDateTimeFromTimeStamp(dateTimestamp))
				.orElse(Lists.newArrayList());
	}

	@Transactional(rollbackFor = Exception.class)
	public void uploadStock(Long strategyId, LocalDateTime uploadDate,
			List<String> stockCodes) {
		// 转时间戳
		LocalDateTime time = LocalDateTime.of(uploadDate.toLocalDate(),
				LocalTime.of(0, 0, 0));
		stockRecommendRepository
				.delStocksByStrategyIdAndUploadDateAndStockCodes(strategyId,
						time);
		redisService.setMaxRecommendTime(
				time.toInstant(ZoneOffset.of("+8")).toEpochMilli());
		List<String> codesWithHouse = stockCodes.stream().distinct()
				.map(StockUtil::getStockCodeWithExchange).filter(StringUtils::isNotEmpty)
				.collect(Collectors.toList());

		if (CollectionUtil.isNotEmpty(codesWithHouse)) {
			String param = Joiner.on(",").join(codesWithHouse);
			String resp = HttpUtil.get(StockConstant.QT_STOCK_URL + param);
			String[] raws = resp.split("\n");
			if (codesWithHouse.size() != raws.length) {
				return;
			}
			for (int i = 0; i < codesWithHouse.size(); i++) {
				String symbol = codesWithHouse.get(i);
				String raw = raws[i];
				String assertion = String.format("(?<=v_%s=\").*?(?=\";)",
						symbol);
				Pattern pattern = Pattern.compile(assertion);
				Matcher matcher = pattern.matcher(raw);
				while (matcher.find()) {
					String[] metas = matcher.group().split("~");
					StockRecommend stock = new StockRecommend();
					stock.setStrategyId(strategyId);
					stock.setStockCode(metas[2]);
					stock.setStockName(metas[1]);
					stock.setLatest(metas[3]);
					stock.setPriceOpen(metas[5]);
					stock.setPriceClose(metas[3]);
					stock.setHigh(metas[33]);
					stock.setLow(metas[34]);

					stock.setPrivateChange(metas[31]);
					stock.setChangeRatio(metas[32]);
					stock.setVolume(metas[36]);
					stock.setTurnover(metas[37]);
					stock.setMarketValue(metas[45]);
					stock.setUploadDate(time);
					stockRecommendRepository.save(stock);
				}
			}
		}
	}
}
